/* Copyright (c) 2004-2024 Peigen.info. All rights reserved. */

package info.peigen.hotpot.component.gateway.core.util;

import cn.hutool.core.codec.BCD;
import cn.hutool.core.util.StrUtil;

import java.math.BigInteger;
import java.util.Arrays;
import java.util.stream.Collectors;

/**
 * <b>(BcdUtil)</b>
 *
 * @author Peigen
 * @version 1.0.0
 * @since 2022/8/17
 */
public class BcdUtil {

    /**
     * 将BCD十六位字符串转为二进制的字符串
     *
     * @param bcdStr String
     *
     * @return 转换后的字符串
     */
    public static String bcdStrToBinaryStr(String bcdStr) {
        return bcdStrToBinaryStr(bcdStr, 2);
    }

    /**
     * 将BCD十六位字符串转为二进制的字符串
     *
     * @param bcdStr String
     * @param bit    位数
     *
     * @return 转换后的字符串
     */
    public static String bcdStrToBinaryStr(String bcdStr, int bit) {
        byte[] bcdBitArray = BCD.strToBcd(bcdStr);
        String binaryStr   = bcdArrayToBinaryStr(bcdBitArray, 2);
        return padLeft(binaryStr, 8 * bit);
    }

    /**
     * 将byte[]转为各种进制的字符串
     *
     * @param bytes byte[]
     * @param radix 基数可以转换进制的范围，从Character.MIN_RADIX到Character.MAX_RADIX，超出范围后变为10进制
     *
     * @return 转换后的字符串
     */
    public static String bcdArrayToBinaryStr(byte[] bytes, int radix) {
        // 这里的1代表正数
        return new BigInteger(1, bytes).toString(radix);
    }

    public static String binaryStrToBcdStr(String bitStr) {
        return binaryStrToBcdStr(bitStr, 2);
    }

    public static String binaryStrToBcdStr(String bitStr, int bit) {
        String[] bitStrArray = StrUtil.split(bitStr, 4);
        String   bcdStr      = Arrays.stream(bitStrArray).map(str -> String.valueOf(Integer.parseInt(str, 2))).collect(Collectors.joining());
        bcdStr = padPre(bcdStr, bit);
        return bcdStr;
    }

    private static String padPre(String str) {
        return padPre(str, 4);
    }

    private static String padPre(String str, int bit) {
        if (str.length() % bit == 0) {
            return str;
        } else {
            str = StrUtil.padPre(str, str.length() + 1, "0");
            padPre(str);
        }
        return str;
    }

    private static String padLeft(String str, int length) {
        return StrUtil.padPre(str, length, "0");
    }
}